﻿using System.Diagnostics;

namespace DimensionsHelper.LanguageService.Syntax;

public class MethodSignature : ModifiedSignatureWithParameters
{
    internal MethodSignature(SyntaxToken declareKeyword, Identifier name, SyntaxNode? parent) :
        base(SyntaxKinds.MethodSignature, declareKeyword, name, parent)
    {
    }


    /// <summary>
    ///     如果函数带有返回值，返回true。
    /// </summary>
    public bool HasReturn => DeclareKeywordToken.IsNode(SyntaxKinds.FunctionKeywordToken);


    protected override string GetFullName()
    {
        Debug.Assert(Parent != null);
        return $"{((ObjectTypeSignature)Parent).Name}.{Name}";
    }


    protected override bool VerifyModifierToken(SyntaxToken token)
    {
        // Nullable
        if (token.IsNode(SyntaxKinds.NullableKeywordToken))
        {
            if (IsNullable)
            {
                return false;
            }

            IsNullable = true;
            return true;
        }

        // Default
        if (!token.IsNode(SyntaxKinds.DefaultKeywordToken) || IsDefault)
        {
            return false;
        }

        IsDefault = true;
        return true;
    }
}


public static partial class NodeFactory
{
    public static MethodSignature CreateMethodSignature(SyntaxNode? parent, SyntaxToken declareKeywordToken,
        IEnumerable<SyntaxToken>? modifiers, Identifier identifierName, IEnumerable<ParameterSignature>? parameters,
        TypeBinding? binding)
    {
        Debug.Assert(declareKeywordToken.IsOneOfNode(SyntaxKinds.SubKeywordToken,
            SyntaxKinds.FunctionKeywordToken));
        MethodSignature signature = new(declareKeywordToken, identifierName, parent);

        if (modifiers != null)
        {
            foreach (SyntaxToken modifier in modifiers)
            {
                signature.TryAddModifier(modifier);
            }
        }

        if (parameters != null)
        {
            foreach (ParameterSignature param in parameters)
            {
                signature.AddParameter(param);
            }
        }

        if (binding != null)
        {
            signature.Update(binding);
        }

        return signature;
    }
}